package com.jwt.controller;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.jwt.entity.User;
import com.jwt.service.UserService;
import com.jwt.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.swing.text.StyleContext;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ：qs
 * @date ：Created in 2022/3/20
 * @description：
 * @modified By：
 */

@RestController
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 实验一 （查询数据登录方式）
     * 不是用jwt登录的逻辑
     *
     * @param user
     * @return
     */
    @GetMapping("/login")
    public Map<String, Object> login(User user) {
        log.info("用户名： [{}]", user.getUserName());
        log.info("用户名： [{}]", user.getPassword());
        Map<String, Object> map = new HashMap<>();
        try {
            // 如果根据传入的用户信息查询不到，直接抛出异常
            // 实际处理过程是对比密码
            User userDB = userService.login(user);
            map.put("state", true);
            map.put("msg", "认证成功～");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("state", false);
            map.put("msg", "认证失败～");
        }
        return map;
    }

    /**
     * 实验二（生产jwt令牌方式）
     * 在上述逻辑中加入jwt令牌
     *
     * @param user
     * @return
     */
    @GetMapping("/login/jwt")
    public Map<String, Object> loginJwT(User user) {
        log.info("用户名： [{}]", user.getUserName());
        log.info("用户名： [{}]", user.getPassword());
        Map<String, Object> map = new HashMap<>();
        try {
            User userDB = userService.login(user);

            // ---------------jwt 逻辑---------------------
            // ---------------根据用户名查询数据库中的用户并对比密码---------------------
            // ---------------密码正确之后，生产jwt并返回---------------------
            Map<String, String> payloadMap = new HashMap<>();
            payloadMap.put("userName", userDB.getUserName());
            payloadMap.put("userId", userDB.getPassword());
            // ---------------生产jwt令牌---------------------
            String token = JWTUtils.getToken(payloadMap);
            map.put("token", token);
            // ---------------jwt 逻辑---------------------

            map.put("state", true);
            map.put("msg", "认证成功～");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("state", false);
            map.put("msg", "认证失败～");
        }
        return map;
    }

    /**
     * 实验二（生产jwt令牌方式，测试token）
     * 模拟该方法需要验证token
     */
    @GetMapping("/user/test")
    public Map<String, Object> test(String token) {
        Map<String, Object> map = new HashMap<>();
        log.info("当前token为：[{}]", token);
        try {
            DecodedJWT verify = JWTUtils.verify(token);
            // todo 验证成功 处理相关逻辑
            // ......................
            // todo 验证成功 处理相关逻辑

            // 成功返回信息
            map.put("state" ,true);
            map.put("msg", "请求成功");
            return map;

            /**
             * 此处捕获异常信息代码冗余 添加拦截器 JWTInterceptor
             */
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            log.info("签名异常～");
            map.put("msg", "签名异常～");
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            log.info("token异常～");
            map.put("msg", "token异常～");
        } catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            log.info("算法异常～");
            map.put("msg", "算法异常～");
        } catch (Exception e){
            e.printStackTrace();
            log.info("未知异常～");
            map.put("msg", "未知异常～");
        }
        // 成功返回信息
        map.put("state" ,false);
        return map;
    }
}
